import {
	sendGrantPwd,
	sendGrantPwdWithoutCenter,
	sendGrantTenantPwd,
	sendGrantNfc,
	sendGrantTenantNfc,
	sendGrantFp,
	sendGrantTenantFp,
	getFpsKey,
	updateLockAuth,
	sendGrantTenantPwdWithoutCenter
} from '@/api/lock'
import {getRenterInfo, getDecisionList, getAssociatedDevice} from '@/api/house'
import {isD3B, isNBPwdLock, isNBFpLock, isD5FpLock, isD5CardLock} from '@/utils/device'
import {AUTH_TYPE_PWD, AUTH_TYPE_IC, AUTH_TYPE_BLUE, AUTH_TYPE_FP} from './const'
import {watch, ref, computed} from 'vue'
import {message, Modal} from 'ant-design-vue'

const isElectron = computed(() => {
	return !!window.DllLibrary
})

async function getTypeOptions(sn) {
	const res = await getDecisionList({module: 'SAFETY', bizPoint: 'SAFETY_SETTING'})
	const setting = (res.data || []).find((v: any) => v.mark === 'SAFETY_LOCK_SETTING')
	if (!setting) {
		return
	}
	const safeValue = JSON.parse(setting.value)
	const lockValue = getLockSetting(sn)
	return [
		{value: AUTH_TYPE_PWD, label: '密码'},
		{value: AUTH_TYPE_IC, label: 'IC卡'},
		{value: AUTH_TYPE_BLUE, label: '蓝牙'},
		{value: AUTH_TYPE_FP, label: '指纹'}
	].filter(type => safeValue.includes(type.value) && lockValue.includes(type.value))
}

function getLockSetting(sn: string) {
	const setting = new Set([AUTH_TYPE_PWD])
	if (isD3B(sn)) setting.add(AUTH_TYPE_BLUE)
	if (isNBPwdLock(sn)) {
		setting.add(AUTH_TYPE_BLUE)
		setting.add(AUTH_TYPE_IC)
	}
	if (isNBFpLock(sn)) {
		setting.add(AUTH_TYPE_BLUE)
		setting.add(AUTH_TYPE_FP)
		setting.add(AUTH_TYPE_IC)
	}
	if (isD5FpLock(sn)) setting.add(AUTH_TYPE_FP)
	if (isD5CardLock(sn)) setting.add(AUTH_TYPE_IC)
	return [...setting].sort()
}

function download() {
	window.open('https://loock-img.oss-cn-qingdao.aliyuncs.com/saas3/%E5%85%AC%E5%AF%93%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9F%20.exe')
}

// 卡模组
const useCardModule = () => {
	const cardData = ref<any>(null)

	function readCard() {
		if (!window.DllLibrary) {
			message.warning('请在客户端操作')
			return
		}

		const res = window.DllLibrary.ReadCard()
		console.log(res)

		if (res.errCode) {
			message.warning(res.errMsg)
			return
		}
		const cardNumber = res.data
		const cardType = res.cardType
		cardData.value = {
			cardNumber,
			cardType
		}
	}

	const  handleAccessByCard = async (data,isVistor = false) =>{
		if (!cardData.value?.cardNumber) {
			message.warning('请先读卡')
			throw new Error('读卡失败')
		}
		data.backRentRemind = 0
		data.cardId = cardData.value.cardNumber
		data.cardName = data.name
		data.cardType = cardData.value.cardType
		const API  = isVistor ? sendGrantTenantNfc : sendGrantNfc
		await API(data)
	}
	function resetCardData() {
		cardData.value = {
			cardNumber: '',
			cardType: ''
		}
	}
	return {
		cardData,
		readCard,
		resetCardData,
		handleAccessByCard
	}
}

// 指纹模组
const useFingerPrintModule = () => {
	const fpTemplateData = ref<any>(null)
	const fpState = ref<any>({
		fpCurrent: 0,
		fpTotal: 6,
		EnrollErrCode: '',
		fpMsg: '--'
	})
	const resetFpData = () => {
		fpState.value = {
			fpCurrent: 0,
			fpTotal: 6,
			EnrollErrCode: '',
			fpMsg: '--'
		}
		fpTemplateData.value = null
	}

	async function uploadFp({deviceId,roomId}) {
		try {
			const {
				data: {secret, key}
			} = await getFpsKey({
				deviceType: 5,
				deviceId,
				roomId,
				withOrigin: true
			})

			const data = window.DllLibrary.DownloadTemplate(secret)
			console.log('DownloadTemplate', data)

			if (data.errCode) {
				fpState.value.fpMsg = `指纹模板下载失败， 错误码${data.errCode}`
				return
			}
			fpState.value.fpMsg = '录入上传完成'
			fpTemplateData.value = {
				template: data.data,
				templateKey: key
			}
		} catch (e) {
			console.log(e)
		} finally {
		}
	}
	function sleep(duration = 500) {
		console.log(`${duration} ms后继续操作`)
		return new Promise(resolve => {
			setTimeout(resolve, duration)
		})
	}
	async function addFp({deviceId, roomId}, isD5Fp) {
		console.log('addFp', {deviceId, roomId}, isD5Fp)

		if (!window.DllLibrary) {
			message.warning('请在客户端操作')
			return
		}

		const sm = window.DllLibrary.StartMonitor(isD5Fp)
		console.log('StartMonitor', sm)
		if (sm.errCode) {
			message.warning(sm.errMsg)
			return
		}

		await sleep()

		// 获取模组版本，确认已连接
		const version = window.DllLibrary.GetFwVersion()
		console.log('GetFwVersion', version)

		if (version.errCode) {
			message.warning(version.errMsg)
			return
		}

		// 开始录入指纹, 回调函数多加1个参数(others)，不然有可能崩溃
		const ee = window.DllLibrary.EnterEnroll((data: any, others: any) => {
			const struct = data.deref()
			console.log('录入指纹回调:')
			console.log({
				iCur: struct.iCur,
				iTotal: struct.iTotal,
				iErrCode: struct.iErrCode,
				iScore: struct.iScore,
				iArea: struct.iArea,
				iCurFingerprintID: struct.iCurFingerprintID
			})
			fpState.value.fpCurrent = struct.iCur
			fpState.value.fpTotal = isD5Fp ? 5 : 6

			fpState.value.EnrollErrCode = struct.iErrCode

			if (fpState.value.fpCurrent === fpState.value.fpTotal) {
				fpState.value.fpMsg = '录入完成，正在上传指纹信息'
				uploadFp({deviceId,roomId})
			} else {
				let desc = '请变换手指角度继续录入指纹'
				if (fpState.value.fpCurrent === 4) {
					desc = '请按手指验证指纹'
				}
				if (fpState.value.fpCurrent === 5) {
					desc = '请再次按手指验证指纹'
				}
				fpState.value.fpMsg = `录入次数: ${fpState.value.fpCurrent}/${fpState.value.fpTotal}; ${desc}`
			}
		})

		if (ee.errCode) {
			message.warning(ee.errMsg)
			return
		}
		fpState.value.fpMsg = `开始录入新指纹，总共需要录入 ${fpState.value.fpTotal} 次`
		return true
	}


	const handleAccessFingerPrint = async (data, isVistor = false, isD5Fp = false) => {
		if (!fpTemplateData.value) {
			message.warning('请先录入指纹')
			throw new Error('请先录入指纹')
		}
		data.backRentRemind = 0
		data.chip = isD5Fp ? 'BF83160E-4/F-4' : 'BTL160M2'
		data.template = fpTemplateData.value.template
		data.templateKey = fpTemplateData.value.templateKey
		const API  = isVistor ? sendGrantFp : sendGrantTenantFp
		await API(data)
		fpState.value.fpMsg = '--'

	}
	return {
		handleAccessFingerPrint,
		resetFpData,
		fpState,
		fpTemplateData,
		addFp
	}
}

const useRenter = () =>{
	const renterInfo = ref<any>({})
	const renterOptions = ref<any[]>([])
	async function getRenter(roomId) {
		const res = await getRenterInfo(roomId)
		renterInfo.value = res.data || {}
		renterOptions.value = (renterInfo.value.renterInfos || []).map((data: any) => {
			const {contractId, phone, id: value, name: label, identityCard, certificationType} = data
			return {value, label, contractId, phone, identityCard, certificationType}
		})
	}
	return {
		renterInfo,
		renterOptions,
		getRenter
	}
}

export {
	useCardModule,
	useFingerPrintModule,
	download,
	getTypeOptions,
	useRenter,
	isElectron
}

